package com.shushan.chant;

import android.text.TextUtils;
import android.util.Log;

import java.util.Random;

/**
 * @ClassName: PEPChant
 * @Desciption: 人教新版口算生成
 * @author: yichaohua
 * @date: 2018-08-31
 */
public class PEPChant {

    private static final String TAG = "PEPChant";

    private static final int HARD_PERCENT = 20;

    /**
     * 过滤0的随机数
     * @param bound
     * @return
     */
    public static int randInt(int bound){
        if(bound == 0){
            return bound;
        }

        int num;
        Random rand = new Random();
        do {
            num = rand.nextInt(bound);
        }while (num == 0 && bound > 1);

        return num;
    }

    /**
     * 1-5的加减法口算练习
     *
     * 和在5以内的加法，被减数最大为5的减法。如：3+2=5；5-4=1
     *
     * @return
     */
    public static int[] chant1(){
        int flag = randInt(3);

        int result = randInt(6);

        int num1 = randInt(result);

        int num2 = result - num1;

        int[] array = new int[4];
        array[0] = flag;
        if(flag == 1){
            array[1] = num1;
            array[2] = num2;
            array[3] = result;
        }else {
            array[1] = result;
            array[2] = num1;
            array[3] = num2;
        }

        return array;
    }

    /**
     * 6-10的加减法口算练习
     *
     * 几加几，和最大为10。 如：9+1=10
     * 十减几或几减几。如：10-8=2；9-6=3
     * 10以内的连加、连减、加减混合运算。和、被减数最大为10。如：5+3+2=10    9-2-3=4     10-6+5=9
     * @return
     */
    public static int[] chant2(){
        int[] array;
        int type = randInt(3);

        int flag = randInt(3);
        if(type == 1){
            array = new int[4];

            int result = new Random().nextInt(5) + 6;
            int num1;
            do {
                num1 = randInt(result);
            }while (num1 == 0);

            int num2 = result - num1;

            array[0] = flag;
            if(flag == 1){
                array[1] = num1;
                array[2] = num2;
                array[3] = result;
            }else {
                array[1] = result;
                array[2] = num1;
                array[3] = num2;
            }
        }else {
            int flag1 = randInt(3);
            array = new int[6];
            array[0] = flag;
            array[1] = flag1;

            int result = new Random().nextInt(5) + 6;
            if(flag == flag1){
                int num1 = randInt(result);
                int num2 = randInt(result - num1 + 1);
                int num3 = result - num1 - num2;
                if(flag == 1){
                    array[2] = num1;
                    array[3] = num2;
                    array[4] = num3;
                    array[5] = result;
                }else {
                    array[2] = result;
                    array[3] = num1;
                    array[4] = num2;
                    array[5] = num3;
                }
            }else {
                int last = randInt(10);
                int sub = 0;
                int addNum = 0;
                do {
                    addNum = randInt(10);
                    sub = result - last + addNum;
                }while (sub <= 0 || sub >= 10);

                if(flag == 1){
                    array[2] = result;
                    array[3] = addNum;
                    array[4] = sub;
                    array[5] = last;
                }else {
                    array[2] = result;
                    array[3] = sub;
                    array[4] = addNum;
                    array[5] = last;
                }
            }
        }

        return array;
    }

    /**
     *10加几、十几加几与相应减法口算练习
     *
     * 10加几、十几加几与十几减几（不进位，不退位）。
     * 如：10+5=15；12+4=16；15-4=11
     * @return
     */
    public static int[] chant3(){
        int[] array = new int[4];
        int flag = randInt(3);
        array[0] = flag;

        int result = new Random().nextInt(10) + 10;
        if(flag == 1){
            int num1 = randInt(20 - result);
            int num2 = result + num1;

            array[1] = result;
            array[2] = num1;
            array[3] = num2;
        }else {
            int num1 = randInt(result - 10 + 1);
            int num2 = result - num1;

            array[1] = result;
            array[2] = num1;
            array[3] = num2;
        }

        return array;
    }

    /**
     * 20以内的进位加法口算练习
     *
     * 几加几，进位加法，和20以内。如：9+8=17 ；7+5=12
     * @return
     */
    public static int[] chant4() {
        int[] array = new int[4];
        array[0] = 1;

        int num1 = randInt(10);
        int sub = 10 - num1;
        int num2 = new Random().nextInt(10 - sub) + sub;

        array[1] = num1;
        array[2] = num2;
        array[3] = num1 + num2;

        return array;
    }

    /**
     *20以内的退位减法口算练习
     *
     * 十几减去9、8、7、6、5、4、3、2的退位减法。
     * 如11-2=9；15-8=7
     * @return
     */
    public static int[] chant5() {
        int[] array = new int[4];
        array[0] = 2;

        int num1 = randInt(9) + 10;
        int sub = num1 - 10;
        int num2 = randInt(10 - sub) + sub;

        array[1] = num1;
        array[2] = num2;
        array[3] = num1 - num2;

        return array;
    }

    /**
     * 整十数加一位数及相应的减法口算练习
     *
     *几十加、减几（被减数个位和减数个位相同），不进位，不退位。
     * 如：70+8=78； 93-3=90
     *
     * 几十几减几十
     * 如：28-20=8；34-30=4
     * @return
     */
    public static int[] chant6() {
        int[] array = new int[4];
        int type = randInt(3);

        int result = (randInt(9) + 1) * 10;
        int num1 = randInt(10);
        if(type == 1){
            int flag = randInt(3);
            array[0] = flag;
            int num2 = result + num1;
            if(flag == 1){
                array[1] = result;
                array[2] = num1;
                array[3] = num2;
            }else {
                array[1] = num2;
                array[2] = num1;
                array[3] = result;
            }
        }else {
            array[0] = 2;

            array[1] = result + num1;
            array[2] = result;
            array[3] = num1;
        }

        return array;
    }

    /**
     *100以内的加法和减法（一）口算练习
     *
     * 几十加、减几十。和与被减数最大为90
     * 如：30+60=90； 90-20=70
     *
     * 两位数加、减一位数（有无进位、退位都可以）
     * 如：86+2=88；46+7=53；28-7=21；36-8=28；
     *
     * 两位数加减整十数。不进位
     * 如：43+50=93；96-60=36
     * @return
     */
    public static int[] chant7() {
        int[] array = new int[4];
        int type = randInt(4);
        int flag = randInt(3);
        array[0] = flag;

        if(type == 1){
            int result = randInt(9) + 1;
            int num1 = randInt(9);
            int num2 = result - num1;

            if(flag == 1){
                array[1] = num1 * 10;
                array[2] = num2 * 10;
                array[3] = result * 10;
            }else {
                array[1] = result * 10;
                array[2] = num1 * 10;
                array[3] = num2 * 10;
            }
        }else if(type == 2){
            int num1 = randInt(10);
            if(flag == 1){
                int result = new Random().nextInt(90 - num1) + 10;

                array[1] = result + num1;
                array[2] = num1;
                array[3] = result;
            }else {
                int result = new Random().nextInt(90) + 10;

                array[1] = result;
                array[2] = num1;
                array[3] = result - num1;
            }

        }else {
            int result = randInt(9) + 1;
            int num1 = randInt(9);
            int num2 = result - num1;
            int num = randInt(10);

            if(flag == 1){
                array[1] = num1 * 10 + num;
                array[2] = num2 * 10;
                array[3] = result * 10 + num;
            }else {
                array[1] = result * 10 + num;
                array[2] = num1 * 10;
                array[3] = num2 * 10 + num;
            }
        }

        return array;
    }

    /**
     * 100以内的加法和减法（二）口算练习
     *
     * 两位数加一位数，两位数（有无进位、退位都可以）
     * 如：43+5=48；29+5=34；35+32=67；25+47=72（少量题目）
     *
     * 两位数减一位数、两位数（有无进位、退位都可以）
     * 如：45-4=41；61-3=59；57-26=31；43-37=26（少量题目）
     *
     * @return
     */
    public static int[] chant8() {
        int[] array = new int[4];
        int flag = randInt(3);
        array[0] = flag;
        int percent = new Random().nextInt(100);
        int result;
        do {
            result = randInt(90) + 10;
        }while ((percent < HARD_PERCENT) &&
                ((result%10 == 9)) || (result <= 30));

        int num1;
        int num2;
        if(percent < HARD_PERCENT){
            do {
                num1 = randInt(result);
                num2 = result - num1;
            }while (num1 <=10 || num2 <= 10 || (num1%10 <= result%10));
        }else {
            do {
                num1 = randInt(result);
                num2 = result - num1;
            }while (num1 > 10 && num2 > 10 && (num1%10 > result%10));
        }

        if(flag == 1){
            array[1] = num1;
            array[2] = num2;
            array[3] = result;
        }else {
            array[1] = result;
            array[2] = num1;
            array[3] = num2;
        }

        return array;
    }

    /**
     * 表内乘法（一）口算练习
     *
     *  2~6的乘法口诀（去乘1-9各数）
     *  如：2×1=2；6×9=54
     *
     *  乘加、乘减， 2~6的乘法口诀内，再加上或者减去一位数
     *  如：6×3+5=23；3×4-7=5
     * @return
     */
    public static int[] chant9() {
        int[] array;
        int type = randInt(4);

        if(type == 1){
            array = new int[4];

            int num1 = randInt(6) + 1;
            int num2 = randInt(10);

            array[1] = num1;
            array[2] = num2;
            array[3] = num1*num2;
        }else {
            array = new int[6];
            int flag = randInt(3);
            array[1] = flag;

            int num1 = randInt(6) + 1;
            int num2 = randInt(10);
            int num3;
            if(flag == 2 && (num1*num2 < 10)){
                num3 = randInt(num1 * num2 + 1);
            }else {
                num3 = randInt(10);
            }

            array[2] = num1;
            array[3] = num2;
            array[4] = num3;
            array[5] = num1 * num2 + num3;
        }

        array[0] = 3;

        return array;
    }

    /**
     * 表内乘法（二）口算练习
     *
     * 7~9的乘法口诀（去乘1-9各数）
     * 如：7×1=7；7×6=42；7×7=49
     * @return
     */
    public static int[] chant10() {
        int[] array = new int[4];
        array[0] = 3;

        int num1 = randInt(4) + 6;
        int num2 = randInt(10);

        array[1] = num1;
        array[2] = num2;
        array[3] = num1 * num2;

        return array;
    }

    /**
     * 表内除法（一）口算练习
     *
     * 用2~6的乘法口诀求商。（除数是1-6的数，商是一位整数）
     * 如：8÷4=2；24 ÷6=4
     * @return
     */
    public static int[] chant11() {
        int[] array = new int[4];
        array[0] = 4;

        int num1 = randInt(7);
        int num2 = randInt(10);

        array[1] = num1 * num2;
        array[2] = num1;
        array[3] = num2;

        return array;
    }

    /**
     * 表内除法（二）口算练习
     *
     * 用7、8、9的乘法口诀求商。（除数是1-9的数，商是一位数）
     * 如：9÷9=1；49÷7=7；64÷8=8
     * @return
     */
    public static int[] chant12() {
        int[] array = new int[4];
        array[0] = 4;

        int num1 = randInt(4) + 6;
        int num2 = randInt(10);

        array[1] = num1 * num2;
        array[2] = num1;
        array[3] = num2;

        return array;
    }

    /**
     * 整百、整千数加减法口算练习
     *
     * 几百加、减几百数
     * 如：300+200=500；600-400=200；
     *
     * 几千加、减几千
     * 如：9000-3000=6000；4000+2000=6000；
     *
     * 几千几百加、减几百数
     * 3400+800=5200； 2500-400=2100
     * @return
     */
    public static int[] chant13() {
        int[] array = new int[4];
        int flag = randInt(3);
        int type = randInt(4);
        array[0] = flag;

        int result = 0;
        int num1;
        int num2;
        if(type == 1){
            result = randInt(9) + 1;
            num1 = randInt(result);
            num2 = result - num1;

            result *= 100;
            num1 *= 100;
            num2 *= 100;
        }else if (type == 2){
            result = randInt(9) + 1;
            num1 = randInt(result);
            num2 = result - num1;

            result *= 1000;
            num1 *= 1000;
            num2 *= 1000;
        }else {
            do {
                num1 = randInt(100);
                num2 = randInt(10);
            }while (flag == 2 && num1 < num2);

            num1 *= 100;
            num2 *= 100;
        }

        if(flag == 1){
            if(type > 2){
                array[1] = num1;
                array[2] = num2;
                array[3] = num1 + num2;
            }else {
                array[1] = num1;
                array[2] = num2;
                array[3] = result;
            }

        }else {
            if(type > 2){
                array[1] = num1;
                array[2] = num2;
                array[3] = num1 - num2;
            }else {
                array[1] = result;
                array[2] = num1;
                array[3] = num2;
            }
        }

        return array;
    }

    /**
     * 1、万以内的加法和减法（一）口算练习
     *
     * 两位数加、减两位数，可进位，退位。
     * 如：48+29=77；47-28=29
     *
     * 几百几十加、减几百几十。（进位，退位只要少量题目）
     * 如：670+250=920；450-260=190
     *
     * @return
     */
    public static int[] chant14() {
        int[] array = new int[4];
        int type = randInt(3);
        int flag = randInt(3);
        array[0] = flag;

        int result;
        int num1;
        int num2;
        if(type == 1){
            num1 = randInt(90) + 10;
            num2 = randInt(num1-10) + 10;

            if(flag == 1){
                result = num1 + num2;
            }else {
                result = num1 - num2;
            }
        }else {
            int percent = new Random().nextInt(100);

            if(percent < HARD_PERCENT){
                do {
                    result = randInt(70) + 30;
                }while (result%10 == 0 || result%10 == 9);

                do {
                    num1 = randInt(result-10) + 10;
                    num2 = result - num1;
                }while (num1%10 == 0 || num2 <= 10 || num2%10 == 0 || (num1%10 <= result%10));
            }else {
                do {
                    result = randInt(80) + 20;
                }while (result%10 <= 1);

                do {
                    num1 = randInt(result-10) + 10;
                    num2 = result - num1;
                }while (num1%10 == 0 || num2%10 == 0 || num2 <= 10 || (num1%10 > result%10));
            }

            result *= 10;
            num1 *= 10;
            num2 *= 10;
        }

        if(flag == 1){
            array[1] = num1;
            array[2] = num2;
            array[3] = result;
        }else {
            array[1] = result;
            array[2] = num1;
            array[3] = num2;
        }

        return array;
    }

    /**
     * 2、万以内的加法和减法（二）口算练习
     *
     * 三位数加、减两位数，可进位，退位
     * 如：460+79=539；350-79=271
     *
     * 三位数加、减三位数。（进位，退位只要少量题目）
     * 如：423+349=772；214-108=106
     * @return
     */
    public static int[] chant15() {
        int[] array = new int[4];
        int type = randInt(3);
        int flag = randInt(3);
        array[0] = flag;

        if(type == 1){
            int num1;
            int num2;
            num1 = randInt(900) + 100;
            num2 = randInt(90) + 10;

            if(flag == 1){
                array[1] = num1;
                array[2] = num2;
                array[3] = num1 + num2;
            }else {
                array[1] = num1;
                array[2] = num2;
                array[3] = num1 - num2;
            }
        }else {
            int num1;
            int num2;
            int percent = new Random().nextInt(100);

            do {
                num1 = randInt(900) + 100;
            }while (percent < HARD_PERCENT
                    && ((flag == 1 && (num1 >= 900 || ((num1%100)==0) || ((num1/100) >=8 && (num1%100) >=90)))
                    || (flag == 2 && (num1 < 210))));

            int a = num1 % 10;
            int b = num1 % 100 / 10;
            int c = num1 / 100;

            Random random = new Random();
            if(percent < HARD_PERCENT){
                int a2;
                int b2;
                do {
                    if(flag == 1){
                        num2 = randInt(900) + 100;
                    }else {
                        num2 = randInt(num1-100) + 100;
                    }

                    a2 = num2 % 10;
                    b2 = num2 % 100 / 10;
                }while ((flag == 1 &&  (((num1+num2)>=10000) || ((a+a2)<10 && (b+b2)<10)))
                        || (flag == 2 && a>=a2 && b>=b2));

            }else {
                if(flag == 1){
                    num2 = randInt(10 - c)*100 + random.nextInt(10 - b)*10 + random.nextInt(10 - a);
                }else {
                    num2 = randInt(c + 1)*100 + random.nextInt(b + 1)*10 + random.nextInt(a + 1);
                }

            }

            if(flag == 1){
                array[1] = num1;
                array[2] = num2;
                array[3] = num1 + num2;
            }else {
                array[1] = num1;
                array[2] = num2;
                array[3] = num1 - num2;
            }
        }

        return array;
    }

    /**
     * 多位数乘一位数口算练习
     *
     * 两位数、三位数乘一位数，不进位
     * 如：32×2=64；124×2=248
     *
     * 整十数、整百数、乘一位数
     * 如：50×4=200；200×7=1400
     *
     * 因数中间或末尾有0的三位数乘一位数。不连续进位。（只要少量题目）
     * 如：203×4=812；160×4=640
     * @return
     */
    public static int[] chant16() {
        int[] array = new int[4];
        array[0] = 3;

        int percent = new Random().nextInt(100);
        if(percent < HARD_PERCENT){
            int type = randInt(3);
            int num1 = randInt(5);
            int num2;
            int num3 = 0;

            do {
                if(num1 >= 4){
                    num2 = randInt(2) + 1;
                }else if(num1 >= 3){
                    num2 = randInt(3) + 1;
                }else if(num1 >= 2){
                    num2 = randInt(4) + 1;
                }else {
                    num2 = randInt(9) + 1;
                }

                if(num2 >= 5){
                    num3 = randInt(9) + 1;
                }else if(num2 >= 4){
                    num3 = randInt(8) + 2;
                }else if(num2 >= 3){
                    num3 = randInt(7) + 3;
                }else if(num2 >= 2){
                    num3 = randInt(6) + 4;
                }
            }while (type == 2 && (num1+(num2*num3)>=10));

            if(type == 1){
                array[1] = num1*100 + num3;
                array[2] = num2;
                array[3] = (num1*100 + num3) * num2;
            }else {
                array[1] = num1*100 + num3*10;
                array[2] = num2;
                array[3] = (num1*100 + num3*10) * num2;
            }
        }else {
            int type = randInt(5);
            Random random = new Random();
            int num1;
            int num2;
            if(type == 1){
                num2 = randInt(9) + 1;
                if(num2 >= 5){
                    num1 = 10 + new Random().nextInt(2);
                }else {
                    int a = randInt(7-num2);
                    int b = randInt(7-num2);
                    num1 = b * 10 + a;
                }
            }else if(type == 2){
                num2 = randInt(9) + 1;
                if(num2 >= 5){
                    num1 = 100 + (random.nextInt(2))*10 + random.nextInt(2);
                }else {
                    int a = random.nextInt(7-num2);
                    int b;
                    if(a == 0){
                        b = randInt(7-num2);
                    }else {
                        b = random.nextInt(7-num2);
                    }
                    int c = randInt(7-num2);

                    num1 = 100*c + 10*b + a;
                }
            }else if(type == 3){
                num1 = 100 * randInt(10);
                num2 = randInt(10);
            }else {
                num1 = 10 * randInt(10);
                num2 = randInt(10);
            }

            array[1] = num1;
            array[2] = num2;
            array[3] = num1 * num2;
        }

        return array;
    }
    public static void test(){
        for (int i = 0 ;i < 40;i++){
            int[] array = chant15();
            String flag = null;
            String flag1 = null;
            if(array.length == 6){
                switch (array[1]){
                    case 1:
                        flag1 = "+";
                        break;
                    case 2:
                        flag1 = "-";
                        break;
                    case 3:
                        flag1 = "*";
                        break;
                    case 4:
                        flag1 = "/";
                        break;
                    default:
                        break;
                }
            }
            switch (array[0]){
                case 1:
                    flag = "+";
                    break;
                case 2:
                    flag = "-";
                    break;
                case 3:
                    flag = "*";
                    break;
                case 4:
                    flag = "/";
                    break;
                default:
                    break;
            }

            if(TextUtils.isEmpty(flag1)){
                Log.i(TAG,array[1] + flag + array[2] + "=" + array[3]);
            }else {
                Log.i(TAG,array[2] + flag + array[3] + flag1 + array[4] + "=" + array[5]);
            }

        }
    }
}
